#include "PrecompiledHeader.h"
#include "ICtrl.h"

/*--------------------------------------------------------------------------*/

ICtrl::ICtrl(ICtrl* parent, const std::string& name)
{
	this->m_childrenCount = 0;
	this->m_parent = parent;
	this->m_name = name;
	this->m_attachedTo = NW;

	this->m_size = glm::vec2();
	this->m_position = glm::vec2();
	this->m_sizePosition = this->m_position + this->m_size;

	if (parent)
	{
		this->m_parent->AddChild(this);
	}
}

/*--------------------------------------------------------------------------*/

ICtrl::~ICtrl()
{
	uint size = this->m_children.size();

	for (uint i = 0; i < size; ++i)
	{
		delete this->m_children[i];
		this->m_children[i] = NULL;
	}
}

/*--------------------------------------------------------------------------*/

ICtrl* ICtrl::GetParent() const
{
	return this->m_parent;
}

/*--------------------------------------------------------------------------*/

void ICtrl::AddChild(ICtrl* child)
{
	this->m_children.push_back(child);
	this->m_childrenCount = this->m_children.size();
}

/*--------------------------------------------------------------------------*/

bool ICtrl::Check()
{
	this->CalculateScreenPosition();
	bool isCMouseOverChild = this->CallChildsCheck();

	glm::vec2 mpos = g_Mouse->GetPosition();

	if (mpos.x > this->m_screenPosition.x && mpos.x < this->m_screenSizePosition.x
	    && mpos.y > this->m_screenPosition.y && mpos.y < this->m_screenSizePosition.y)
	{
		if (this->m_CMouseOver == false)
		{
			this->OnCMouseIn();
		}

		this->m_CMouseOver = true;

		if (isCMouseOverChild == false)
		{
			this->OnCMouseOver();
		}

		if (isCMouseOverChild == false && g_Mouse->GetKeyState(EKey::LMB))
		{
			if ((this->m_CMouseLMBClick == true && this->m_CMouseLMBDrag == false) || this->m_CMouseLMBDrag == true)
			{
				if (this->m_CMouseLMBClick)
				{
					this->m_LMBDragLastPosition = mpos;
				}

				this->m_CMouseLMBClick = false;
				this->m_CMouseLMBDrag = true;
				this->OnLMBDrag(glm::vec2(mpos - this->m_screenPosition), this->m_LMBDragLastPosition - mpos);
				this->m_LMBDragLastPosition = mpos;
			}
			else
			{
				this->m_CMouseLMBDrag = false;
				this->m_CMouseLMBClick = true;
				this->OnLMBClick(mpos - this->m_screenPosition);
			}
		}
		else
		{
			this->m_CMouseLMBDrag = false;
			this->m_CMouseLMBClick = false;
		}

		if (isCMouseOverChild == false && g_Mouse->GetKeyState(EKey::RMB))
		{
			if ((this->m_CMouseRMBClick == true && this->m_CMouseRMBDrag == false) || this->m_CMouseRMBDrag == true)
			{
				if (this->m_CMouseRMBClick)
				{
					this->m_RMBDragLastPosition = mpos;
				}

				this->m_CMouseRMBClick = false;
				this->m_CMouseRMBDrag = true;
				this->OnRMBDrag(glm::vec2(mpos - this->m_screenPosition), this->m_RMBDragLastPosition - mpos);

				this->m_RMBDragLastPosition = mpos;
			}
			else
			{
				this->m_CMouseRMBDrag = false;
				this->m_CMouseRMBClick = true;
				this->OnRMBClick(mpos - this->m_screenPosition);
			}
		}
		else
		{
			this->m_CMouseRMBDrag = false;
			this->m_CMouseRMBClick = false;
		}

		return true;
	}
	else
	{
		if (this->m_CMouseOver == true)
		{
			this->OnCMouseOut();
		}

		this->m_CMouseOver = false;
		this->m_CMouseLMBClick = false;
		this->m_CMouseLMBDrag = false;
		this->m_CMouseRMBClick = false;
		this->m_CMouseRMBDrag = false;

		return false;
	}
}

/*--------------------------------------------------------------------------*/

const glm::vec2& ICtrl::GetPosition() const
{
	return this->m_position;
}

/*--------------------------------------------------------------------------*/

void ICtrl::SetPosition(const glm::vec2& npos)
{
	this->m_position = npos;
	this->m_sizePosition = this->m_position + this->m_size;
}

/*--------------------------------------------------------------------------*/

const glm::vec2& ICtrl::GetSize() const
{
	return this->m_size;
}

/*--------------------------------------------------------------------------*/

void ICtrl::SetSize(const glm::vec2& nsize)
{
	this->m_size = nsize;
	this->m_sizePosition = this->m_position + this->m_size;
}

/*--------------------------------------------------------------------------*/

bool ICtrl::CallChildsCheck()
{
	bool isOverChild = false;

	for (uint i = 0; i < this->m_childrenCount; ++i)
	{
		isOverChild |= this->m_children[i]->Check();
	}

	return isOverChild;
}

/*--------------------------------------------------------------------------*/

void ICtrl::CallChildsDraw()
{
	for (uint i = 0; i < this->m_childrenCount; ++i)
	{
		this->m_children[i]->Draw();
	}
}

/*--------------------------------------------------------------------------*/

void ICtrl::ReadSpecials(std::ifstream& file, const std::string& firstWord)
{
}

/*--------------------------------------------------------------------------*/

void ICtrl::OnCMouseOver()
{
// 	std::stringstream ss;
// 	ss << "echo " << " onCMouseOver " << this->m_name;
// 	g_Shell->Execute(ss.str());
}

/*--------------------------------------------------------------------------*/

void ICtrl::OnCMouseIn()
{
// 	std::stringstream ss;
// 	ss << "echo " << " onCMouseIn " << this->m_name;
// 	g_Shell->Execute(ss.str());
}

/*--------------------------------------------------------------------------*/

void ICtrl::OnCMouseOut()
{
// 	std::stringstream ss;
// 	ss << "echo " << " onCMouseOut " << this->m_name;
// 	g_Shell->Execute(ss.str());
}

/*--------------------------------------------------------------------------*/

const ICtrl::AttachedTo& ICtrl::GetAttachedTo() const
{
	return this->m_attachedTo;
}

/*--------------------------------------------------------------------------*/

void ICtrl::SetAttachedTo(const AttachedTo& att)
{
	this->m_attachedTo = att;
}

/*--------------------------------------------------------------------------*/

void ICtrl::CalculateScreenPosition()
{
	if (this->m_parent == NULL)
	{
		if (this->m_attachedTo == NW)
		{
			this->m_screenPosition = this->m_position;
		}
		else if (this->m_attachedTo == NE)
		{
			glm::vec2 res = g_Settings->GetResolutionf();
			this->m_screenPosition = glm::vec2(res.x - this->m_sizePosition.x, this->m_position.y);
		}
		else if (this->m_attachedTo == SE)
		{
			glm::vec2 res = g_Settings->GetResolutionf();
			this->m_screenPosition = glm::vec2(res.x - this->m_sizePosition.x, res.y - this->m_sizePosition.y);
		}
		else if (this->m_attachedTo == SW)
		{
			glm::vec2 res = g_Settings->GetResolutionf();
			this->m_screenPosition = glm::vec2(this->m_position.x, res.y - this->m_sizePosition.y);
		}
	}
	else
	{
		if (this->m_attachedTo == NW)
		{
			this->m_screenPosition = this->m_parent->m_screenPosition + this->m_position;
		}
		else if (this->m_attachedTo == NE)
		{
			glm::vec2 res = this->m_parent->m_screenSizePosition;
			this->m_screenPosition = glm::vec2(res.x - this->m_sizePosition.x,
			                                   this->m_parent->m_screenPosition.y + this->m_position.y);
		}
		else if (this->m_attachedTo == SE)
		{
			glm::vec2 res = this->m_parent->m_screenSizePosition;
			this->m_screenPosition = glm::vec2(res.x - this->m_sizePosition.x,
			                                   res.y - this->m_sizePosition.y);
		}
		else if (this->m_attachedTo == SW)
		{
			glm::vec2 res = this->m_parent->m_screenSizePosition;
			this->m_screenPosition = glm::vec2(this->m_parent->m_screenPosition.x + this->m_position.x,
			                                   res.y - this->m_sizePosition.y);
		}
	}

	this->m_screenSizePosition = this->m_screenPosition + this->m_size;
}

/*--------------------------------------------------------------------------*/

void ICtrl::OnLMBClick(const glm::vec2& clickPosition)
{
// 	std::stringstream ss;
// 	ss << "echo " << " onLMBClick " << this->m_name;
// 	g_Shell->Execute(ss.str());
}

/*--------------------------------------------------------------------------*/

void ICtrl::OnRMBClick(const glm::vec2& clickPosition)
{
// 	std::stringstream ss;
// 	ss << "echo " << " onRMBClick " << this->m_name;
// 	g_Shell->Execute(ss.str());
}

/*--------------------------------------------------------------------------*/

void ICtrl::OnLMBDrag(const glm::vec2& clickPosition, const glm::vec2& movement)
{
// 	std::stringstream ss;
// 	ss << "echo " << " onLMBDrag " << this->m_name;
// 	g_Shell->Execute(ss.str());
}

/*--------------------------------------------------------------------------*/

void ICtrl::OnRMBDrag(const glm::vec2& clickPosition, const glm::vec2& movement)
{
// 	std::stringstream ss;
// 	ss << "echo " << " onRMBDrag " << this->m_name;
// 	g_Shell->Execute(ss.str());
}

/*--------------------------------------------------------------------------*/